package dbsvc

import (
	"server/application/db/system/columns"
	"server/application/db/system/dbdto"
	"server/pkg/where"
	"sort"
	"strings"
)

// SysMenuTree 状结构的菜单(根据前端框架来构建)
type SysMenuTree struct {
	ID          uint          `json:"id"`
	Name        string        `json:"name"`
	Title       string        `json:"title"`
	Path        string        `json:"path"`
	Sort        uint          `json:"sort"`
	ParentId    uint          `json:"parent_id"`
	Permissions string        `json:"permissions"`
	Component   string        `json:"component"`
	Meta        SysMenuMeta   `json:"meta"`
	Children    []SysMenuTree `json:"children"`
}

// SysMenuTreePermission 树形菜单-权限设置的时候用到
type SysMenuTreePermission struct {
	ID            uint                    `json:"id"`
	Name          string                  `json:"name"`
	IsPenultimate bool                    `json:"is_penultimate"` //倒数第二节点
	Title         string                  `json:"title"`
	Sort          uint                    `json:"sort"`
	ParentId      uint                    `json:"parent_id"`
	IsPermission  bool                    `json:"is_permission"` //节点是否为权限
	Children      []SysMenuTreePermission `json:"children"`
}

// SysMenuMeta 菜单元数据
type SysMenuMeta struct {
	Icon        string `json:"icon"`
	Title       string `json:"title"`
	IsLink      string `json:"isLink"`
	IsHide      bool   `json:"isHide"`
	IsFull      bool   `json:"isFull"`
	IsAffix     bool   `json:"isAffix"`
	IsKeepAlive bool   `json:"isKeepAlive"`
}

// BuildMenuTree 根据数据库数据列表递归构造树状数据结构，将数据库返回的列表组装前端所需
//
//	假设从数据库中获取了AdMenu列表数据 var menus []AdMenu
//
// menuTree := BuildMenuTree(menus, "") //此时menuTree变量保存了树状结构的数据
func BuildMenuTree(menus []*dbdto.SysMenuInfo, parentId uint) []SysMenuTree {
	var tree []SysMenuTree
	for _, menu := range menus {
		if menu.ParentId == parentId {
			node := SysMenuTree{
				ID:          menu.ID,
				Name:        menu.Name,
				Title:       menu.Title,
				Path:        menu.Path,
				Sort:        menu.Sort,
				ParentId:    menu.ParentId,
				Component:   menu.Component,
				Permissions: menu.Permissions, //权限列表
				Meta: SysMenuMeta{
					Icon:        menu.Icon,
					Title:       menu.Title,
					IsLink:      menu.IsLink,
					IsHide:      menu.IsHide,
					IsFull:      menu.IsFull,
					IsAffix:     menu.IsAffix,
					IsKeepAlive: menu.IsKeepAlive,
				},
			}
			if menu.ID != 0 {
				children := BuildMenuTree(menus, menu.ID)
				node.Children = children
			}
			tree = append(tree, node)
		}
	}
	return tree
}

// BuildMenuTreePermission 构造菜单选择
func BuildMenuTreePermission(menus []*dbdto.SysMenuInfo, parentId uint) []SysMenuTreePermission {
	var tree []SysMenuTreePermission
	for _, menu := range menus {
		if menu.ParentId == parentId {
			node := SysMenuTreePermission{
				ID:    menu.ID,
				Name:  menu.Name,
				Title: menu.Title,
				Sort:  menu.Sort,
			}
			if menu.ID != 0 {
				children := BuildMenuTreePermission(menus, menu.ID)
				node.Children = children
			}
			tree = append(tree, node)
		}
	}
	return tree
}

// SysMenuTreeSelect 树形菜单选择器
type SysMenuTreeSelect struct {
	Value    uint                `json:"value"`
	Label    string              `json:"label"`
	Sort     uint                `json:"sort"`
	Children []SysMenuTreeSelect `json:"children"`
}

// BuildAdMenuTreeSelect 构造树形菜单选择器
func BuildAdMenuTreeSelect(menus []*dbdto.SysMenuInfo, parentId uint) []SysMenuTreeSelect {
	var tree []SysMenuTreeSelect
	for _, menu := range menus {
		if menu.ParentId == parentId {
			node := SysMenuTreeSelect{
				Value: menu.ID,
				Label: menu.Title,
				Sort:  menu.Sort,
			}
			if menu.ID != 0 {
				children := BuildAdMenuTreeSelect(menus, menu.ID)
				node.Children = children
			}
			tree = append(tree, node)
		}
	}
	return tree
}

// SortTreeSelectBySort 按照sort对属性结果进行排序进行排序
func SortTreeSelectBySort(tree []SysMenuTreeSelect) []SysMenuTreeSelect {
	sort.Slice(tree, func(i, j int) bool {
		return tree[i].Sort > tree[j].Sort
	})
	for i := range tree {
		tree[i].Children = SortTreeSelectBySort(tree[i].Children)
	}
	return tree
}

// SortMenuTree 按照sort对属性结果进行排序进行排序
func SortMenuTree(tree []SysMenuTree) []SysMenuTree {
	sort.Slice(tree, func(i, j int) bool {
		return tree[i].Sort > tree[j].Sort
	})
	for i := range tree {
		tree[i].Children = SortMenuTree(tree[i].Children)
	}
	return tree
}

// SortTreePermissionBySort 按照sort对属性结果进行排序进行排序
func SortTreePermissionBySort(tree []SysMenuTreePermission) []SysMenuTreePermission {
	sort.Slice(tree, func(i, j int) bool {
		return tree[i].Sort > tree[j].Sort
	})
	for i := range tree {
		tree[i].Children = SortTreePermissionBySort(tree[i].Children)
	}
	return tree
}

// MenuTreeAddChildrenToLeafNodes 在叶子节点上添加权限列表
func MenuTreeAddChildrenToLeafNodes(tree []SysMenuTreePermission) {
	for i := 0; i < len(tree); i++ {
		if len(tree[i].Children) > 0 {
			// 递归遍历子节点
			MenuTreeAddChildrenToLeafNodes(tree[i].Children)
		} else {
			//叶子结点，新增权限子节点
			tree[i].IsPenultimate = true //倒数第二节点
			menuInfo, err := SysMenuFindOne(where.Format(where.Opt(columns.SysMenuID, "=", tree[i].ID)))
			if err != nil {
				continue
			}
			if menuInfo.ID <= 0 || menuInfo.Permissions == "" {
				continue
			}
			PermissionItemList := strings.Split(menuInfo.Permissions, ",")
			PermissionList := make([]SysMenuTreePermission, 0)
			//构造数据
			for _, permissionName := range PermissionItemList {
				item := SysMenuTreePermission{
					Name:         menuInfo.Name + "." + permissionName, //权限标识：菜单名+权限名
					Title:        permissionName,
					IsPermission: true, //节点为权限
					ParentId:     menuInfo.ID,
					Children:     nil,
				}
				PermissionList = append(PermissionList, item)
			}

			tree[i].Children = PermissionList
		}
	}
}
